package rs.belex.belexdroid.activities;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;

import rs.belex.belexdroid.R;
import rs.belex.belexdroid.accessor.InvalidBackendResponse;
import rs.belex.belexdroid.beans.ShareBean;
import rs.belex.belexdroid.beans.StockQuoteBean;
import rs.belex.belexdroid.beans.interfaces.Account;
import rs.belex.belexdroid.beans.interfaces.Share;
import rs.belex.belexdroid.beans.interfaces.StockQuote;
import rs.belex.belexdroid.beans.interfaces.User;
import rs.belex.belexdroid.handler.StockQuoteHandler;
import rs.belex.belexdroid.service.StockQuoteService;
import rs.belex.belexdroid.services.impl.ksoap2.AccountProviderKsoap2Impl;
import rs.belex.belexdroid.services.impl.ksoap2.LoginKsoap2Impl;
import rs.belex.belexdroid.services.interfaces.IAccountProvider;
import rs.belex.belexdroid.services.interfaces.ILogin;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.text.Spannable;
import android.text.style.UnderlineSpan;
import android.view.KeyEvent;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnKeyListener;
import android.view.animation.Animation;
import android.view.animation.RotateAnimation;
import android.widget.ArrayAdapter;
import android.widget.AutoCompleteTextView;
import android.widget.Button;
import android.widget.EditText;
import android.widget.ImageView;
import android.widget.RelativeLayout;
import android.widget.TabHost;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

public class GetStockQuote extends Activity implements OnClickListener,
		OnKeyListener {
	private static final int ADD_STOCK_TO_PORTFOLIO_EVENT = 1;
	private static final int GET_QUOTE_EVENT = 2;
	private static final DateFormat dateFormat = new SimpleDateFormat(
			"h:mmaa 'on' EEE, d MMM yyyy");
	private final IAccountProvider accountProvider = new AccountProviderKsoap2Impl();
	private TextView lastTradedValue, dateValue, changeValue, stockSymbolValue,
			companyNameValue, openingPriceValue, closingPriceValue,
			dayHighValue, dayLowValue, buyingVolumeValue, sellingVolumeValue,
			volumeValue, volumePriceValue, typeValue, methodValue,
			screenRefreshTimeValue;
	private static List<String> SYMBOLS = new ArrayList<String>();
	private String username, password;
	private User user;
	private AutoCompleteTextView symbolWidget, myPortfolioWidget;
	private ImageView changeImageView;
	private Button getQuoteButton, chartButton, addSymbolButton,
			refreshPortfolioButton, addSymbolErrorCloseButton,
			getQuoteErrorCloseButton;
	private TabHost tabHost;
	private Map<String, TableRow> symbols;

	/** Called when the activity is first created. */
	@Override
	public void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);

		setContentView(R.layout.portfolio);
		stockSymbolValue = (TextView) findViewById(R.id.stockSymbolValue);
		companyNameValue = (TextView) findViewById(R.id.companyNameValue);
		lastTradedValue = (TextView) findViewById(R.id.lastTradedValue);

		changeImageView = (ImageView) findViewById(R.id.changeImage);
		changeValue = (TextView) findViewById(R.id.changeValue);
		dateValue = (TextView) findViewById(R.id.dateValue);
		openingPriceValue = (TextView) findViewById(R.id.openingPriceValue);
		closingPriceValue = (TextView) findViewById(R.id.closingPriceValue);
		dayHighValue = (TextView) findViewById(R.id.dayHighValue);
		dayLowValue = (TextView) findViewById(R.id.dayLowValue);
		buyingVolumeValue = (TextView) findViewById(R.id.buyingVolume);
		sellingVolumeValue = (TextView) findViewById(R.id.sellingVolume);
		volumeValue = (TextView) findViewById(R.id.volumeValue);
		volumePriceValue = (TextView) findViewById(R.id.volumePriceValue);
		typeValue = (TextView) findViewById(R.id.typeValue);
		methodValue = (TextView) findViewById(R.id.methodValue);

		screenRefreshTimeValue = (TextView) findViewById(R.id.screenRefreshTimeValue);

		getQuoteButton = (Button) findViewById(R.id.submitSymbol);
		getQuoteButton.setOnClickListener(this);

		chartButton = (Button) findViewById(R.id.lineChart);
		chartButton.setOnClickListener(this);

		addSymbolButton = (Button) findViewById(R.id.myPortfolioSubmitSymbol);
		addSymbolButton.setOnClickListener(this);

		refreshPortfolioButton = (Button) findViewById(R.id.myPortfolioRefreshPortfolio);
		refreshPortfolioButton.setOnClickListener(this);

		myPortfolioWidget = (AutoCompleteTextView) findViewById(R.id.myPortfolioSymbol);
		myPortfolioWidget.setOnKeyListener(this);

		symbolWidget = (AutoCompleteTextView) findViewById(R.id.symbol);
		symbolWidget.setOnKeyListener(this);

		tabHost = (TabHost) findViewById(R.id.tabhost);

		tabHost.setup();
		TabHost.TabSpec fav = tabHost.newTabSpec("favQuoteTab");
		fav.setContent(R.id.rlFavQuote);
		fav.setIndicator("Portfolio", getResources().getDrawable(
				R.drawable.portfolio));
		tabHost.addTab(fav);
		TabHost.TabSpec spec = tabHost.newTabSpec("getQuoteTab");
		spec.setContent(R.id.rlGetQuote);
		spec.setIndicator("Dnevna Stat.", getResources().getDrawable(
				R.drawable.quote));
		tabHost.addTab(spec);
		tabHost.setCurrentTab(0);

		addSymbolErrorCloseButton = (Button) findViewById(R.id.addSymbolErrorClose);
		addSymbolErrorCloseButton.setOnClickListener(this);

		getQuoteErrorCloseButton = (Button) findViewById(R.id.getQuoteErrorClose);
		getQuoteErrorCloseButton.setOnClickListener(this);
		/** Disabling shared preferences */
		symbols = new HashMap<String, TableRow>();
		// Not working
		// SharedPreferences preferences = super.getPreferences(MODE_PRIVATE);
		// username = preferences.getString("username", null);
		// password = preferences.getString("password", null);
		String[] userData = getIntent().getStringArrayExtra("userData");
		username = userData[0];
		password = userData[1];
		ILogin login = new LoginKsoap2Impl();
		/**
		 * Fetching non persistent object. Some day this should be done by
		 * SQLite
		 */
		user = login.login(username, password);
		List<Share> shares = user.getAccount().getShares();
		for (Share share : shares) {
			StockQuote stockQuote = new StockQuoteBean();
			stockQuote.setSymbol(share.getSymbol());
			symbols.put(share.getSymbol(), addStockToPortfolioList(stockQuote));
		}

		refreshSymbols();
	}

	private void refreshSymbols() {
		if (!symbols.isEmpty()) {
			showProcessingImage(R.id.myPortfolioLoadingImageView);
			getQuotes((String[]) symbols.keySet().toArray(new String[0]),
					ADD_STOCK_TO_PORTFOLIO_EVENT);
		}
	}

	public void onClick(View view) {
		String symbol = null;
		int event = 0;
		/** GET QUOTE is clicked */
		if (view == getQuoteButton) {
			symbol = getSearchedKeyWord(R.id.symbol);
			if (symbol == null || symbol.trim().length() == 0) {
				return;
			}
			cleanupPreviousGetQuoteResults();
			showProcessingImage(R.id.loadingImageView);

			event = GET_QUOTE_EVENT;

		}/** CHART button is clicked */
		else if (view == chartButton) {
			//TODO link button to charting activity
		}/** ADD SYMBOL is clicked */
		else if (view == addSymbolButton) {
			symbol = getSearchedKeyWord(R.id.myPortfolioSymbol);
			if (symbol == null || symbol.trim().length() == 0) {
				return;
			}
			if (symbols.containsKey(symbol)) {
				InvalidBackendResponse invalidBackendResponse = new InvalidBackendResponse(
						-2, "Duplicate Entry attempted");
				updateStock(invalidBackendResponse,
						ADD_STOCK_TO_PORTFOLIO_EVENT);
				return;
			}
			StockQuote stockQuote = new StockQuoteBean();
			stockQuote.setSymbol(symbol);
			symbols.put(symbol, addStockToPortfolioList(stockQuote));
			showProcessingImage(R.id.myPortfolioLoadingImageView);
			addShareToUserAccount(symbol);
			event = ADD_STOCK_TO_PORTFOLIO_EVENT;

		}/** REFRESH is clicked */
		else if (view == refreshPortfolioButton) {
			refreshSymbols();
			return;

		} else if (view == addSymbolErrorCloseButton) {
			RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rlAddSymbolError);
			relativeLayout.setVisibility(View.GONE);
			return;

		} else if (view == getQuoteErrorCloseButton) {
			RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rlgetQuoteError);
			relativeLayout.setVisibility(View.GONE);
			return;
		}
		/**This is only to prevent service call when chart event*/
		if (!(view == chartButton))
			getQuotes(new String[] { symbol }, event);
	}

	public GetStockQuote() {
		// TODO Auto-generated constructor stub
	}

	// @Override
	// protected void onStop() {
	// super.onStop();
	// SharedPreferences preferences = getPreferences(MODE_PRIVATE);
	// SharedPreferences.Editor editor = preferences.edit();
	// editor.clear();
	// Iterator<String> symbolSetIterator = symbols.keySet().iterator();
	// while (symbolSetIterator.hasNext()) {
	// editor.putString(symbolSetIterator.next(), null);
	// }
	// editor.commit();
	// }

	private void getQuotes(String[] symbols, int event) {
		StockQuoteHandler handler = new StockQuoteHandler(this, event);
		StockQuoteService stockQuoteService = new StockQuoteService(symbols,
				handler);

		Thread thread = new Thread(stockQuoteService);
		thread.start();
	}

	private String getSearchedKeyWord(int editTextId) {
		String symbol;
		EditText symbolWidget = (EditText) findViewById(editTextId);
		symbol = symbolWidget.getText().toString().toUpperCase();
		return symbol;
	}

	private void cleanupPreviousGetQuoteResults() {
		stockSymbolValue.setText("");
		companyNameValue.setText("");
		lastTradedValue.setText("");
		dateValue.setText("");
		changeImageView.setImageResource(0);
		changeValue.setText("");
		openingPriceValue.setText("");
		closingPriceValue.setText("");
		dayHighValue.setText("");
		dayLowValue.setText("");
		buyingVolumeValue.setText("");
		sellingVolumeValue.setText("");
		volumeValue.setText("");
		volumePriceValue.setText("");
		typeValue.setText("");
		methodValue.setText("");

	}

	private void showProcessingImage(int imageViewId) {
		ImageView imageView = (ImageView) findViewById(imageViewId);
		imageView.setImageResource(R.drawable.loading);
		RotateAnimation rotateAnimation = new RotateAnimation(0, 360, 13, 13);
		rotateAnimation.setDuration(1000);
		rotateAnimation.setRepeatCount(Animation.INFINITE);
		imageView.startAnimation(rotateAnimation);
	}

	/** Refreshes values in table. Called each time new stockQuote is added */
	public void updateStock(Object object, int event) {
		if (object.getClass().isArray()) {
			StockQuote[] stockQuotes = (StockQuote[]) object;
			if (event == ADD_STOCK_TO_PORTFOLIO_EVENT) {
				for (int i = 0; i < stockQuotes.length; i++) {
					updateStockInformationInPortfolio(stockQuotes[i], symbols
							.get(stockQuotes[i].getSymbol()));
				}
				stopAnimation(R.id.myPortfolioLoadingImageView);
				screenRefreshTimeValue.setText("Last updated at: "
						+ dateFormat.format(new Date()));
			} else if (event == GET_QUOTE_EVENT) {
				for (int i = 0; i < stockQuotes.length; i++) {
					displayStockInfo(stockQuotes[i]);
				}
				stopAnimation(R.id.loadingImageView);
			} else {
				InvalidBackendResponse backendResponse = new InvalidBackendResponse(
						-2, "Program Error:Invalid Event Code returned");
				displayErrorMessage(backendResponse, 3);
				return;
			}

			for (int i = 0; i < stockQuotes.length; i++) {
				addToDropDownList(stockQuotes[i].getSymbol());
			}

		} else {
			InvalidBackendResponse backendResponse = (InvalidBackendResponse) object;
			displayErrorMessage(backendResponse, event);
			if (event == ADD_STOCK_TO_PORTFOLIO_EVENT) {
				stopAnimation(R.id.myPortfolioLoadingImageView);
			} else if (event == GET_QUOTE_EVENT) {
				stopAnimation(R.id.loadingImageView);
			}
		}
	}

	private void stopAnimation(int imageViewId) {
		ImageView imageView = (ImageView) findViewById(imageViewId);
		imageView.clearAnimation();
		imageView.setImageResource(0);
	}

	private TableRow addStockToPortfolioList(StockQuote stockQuote) {
		final TableLayout tableLayout = (TableLayout) findViewById(R.id.myPortfolioTable);
		final TableRow tableRow = new TableRow(this);

		final TextView myPortfolioSymbolLabel = new TextView(this);
		myPortfolioSymbolLabel.setId(1);
		myPortfolioSymbolLabel.setPadding(5, 5, 5, 5);
		final String symbol = stockQuote.getSymbol();
		myPortfolioSymbolLabel.setText(symbol, TextView.BufferType.SPANNABLE);
		Spannable str = (Spannable) myPortfolioSymbolLabel.getText();
		str.setSpan(new UnderlineSpan(), 0, symbol.length(),
				Spannable.SPAN_EXCLUSIVE_EXCLUSIVE);
		myPortfolioSymbolLabel.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				tabHost.setCurrentTab(1);
				symbolWidget.setText(myPortfolioSymbolLabel.getText());
				getQuoteButton.performClick();
			}
		});
		tableRow.addView(myPortfolioSymbolLabel);

		TextView myPortfolioSymbolValue = new TextView(this);
		/** sets identifier for this view */
		myPortfolioSymbolValue.setId(2);

		myPortfolioSymbolValue.setPadding(5, 5, 5, 5);
		myPortfolioSymbolValue.setTextColor(Color.YELLOW);
		tableRow.addView(myPortfolioSymbolValue);

		ImageView myPortfolioSymbolChangeImage = new ImageView(this);
		myPortfolioSymbolChangeImage.setId(3);
		myPortfolioSymbolChangeImage.setPadding(5, 8, 5, 2);
		tableRow.addView(myPortfolioSymbolChangeImage);

		TextView myPortfolioSymbolChangeValue = new TextView(this);
		myPortfolioSymbolChangeValue.setId(4);
		myPortfolioSymbolChangeValue.setPadding(5, 5, 5, 5);
		tableRow.addView(myPortfolioSymbolChangeValue);

		ImageView removeSymbolView = new ImageView(this);
		removeSymbolView.setPadding(5, 5, 5, 5);
		removeSymbolView.setImageResource(R.drawable.remove_button);
		removeSymbolView.setOnClickListener(new View.OnClickListener() {
			public void onClick(View view) {
				symbols.remove(symbol);
				tableRow.setVisibility(View.GONE);
				tableLayout.removeView(tableRow);
				assignRowColor(tableLayout);
				deleteShareFromUserAccount(symbol);
			}
		});
		tableRow.addView(removeSymbolView);
		tableLayout.addView(tableRow);
		assignRowColor(tableLayout);

		myPortfolioWidget.setText("");
		return tableRow;

	}

	private void updateStockInformationInPortfolio(StockQuote stockQuote,
			TableRow tableRow) {
		if (tableRow == null) {
			return;
		}
		TextView myPortfolioSymbolValue = (TextView) tableRow.findViewById(2);
		TextView myPortfolioSymbolChangeValue = (TextView) tableRow
				.findViewById(4);
		ImageView myPortfolioSymbolChangeImage = (ImageView) tableRow
				.findViewById(3);
		myPortfolioSymbolValue.setText(stockQuote.getLastTradedPrice() + "");
		setChangeInformation(stockQuote, myPortfolioSymbolChangeValue,
				myPortfolioSymbolChangeImage);

	}

	private void addToDropDownList(String symbol) {
		if (!SYMBOLS.contains(symbol)) {
			SYMBOLS.add(symbol);
			ArrayAdapter<String> adapter = new ArrayAdapter<String>(this,
					android.R.layout.simple_dropdown_item_1line, SYMBOLS);
			symbolWidget.setAdapter(adapter);

		}
	}

	private void displayErrorMessage(InvalidBackendResponse backendResponse,
			int event) {
		if (event == ADD_STOCK_TO_PORTFOLIO_EVENT) {
			TextView errorTextView = (TextView) findViewById(R.id.addSymbolErrorText);
			errorTextView.setText(backendResponse.toString());
			RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rlAddSymbolError);
			relativeLayout.setVisibility(View.VISIBLE);
		} else {
			TextView errorTextView = (TextView) findViewById(R.id.getQuoteErrorText);
			errorTextView.setText(backendResponse.toString());
			RelativeLayout relativeLayout = (RelativeLayout) findViewById(R.id.rlgetQuoteError);
			relativeLayout.setVisibility(View.VISIBLE);
		}

	}

	private void displayStockInfo(StockQuote stockQuote) {

		stockSymbolValue.setText(stockQuote.getSymbol());
		companyNameValue.setText(stockQuote.getCompanyName());
		lastTradedValue
				.setText(String.valueOf(stockQuote.getLastTradedPrice()));

		setChangeInformation(stockQuote, changeValue, changeImageView);

		dateValue.setText(stockQuote.getFormatedDate());
		closingPriceValue.setText(stockQuote.getLastTradedPrice() + "");
		if (stockQuote.getOpeningPrice() == null) {
			openingPriceValue.setText("/");
			dayHighValue.setText("/");
			dayLowValue.setText("/");
		} else {
			openingPriceValue.setText(stockQuote.getOpeningPrice() + "");
			dayHighValue.setText(stockQuote.getDayHighPrice() + "");
			dayLowValue.setText(stockQuote.getDayLowPrice() + "");
		}
		if (stockQuote.getBuyingVolume() == null
				|| stockQuote.getSellingVolume() == null) {
			buyingVolumeValue.setText("/");
			sellingVolumeValue.setText("/");
		} else {
			buyingVolumeValue.setText(stockQuote.getBuyingVolume() + "");
			sellingVolumeValue.setText(stockQuote.getSellingVolume() + "");
		}
		volumeValue.setText(stockQuote.getVolume() + "");
		volumePriceValue.setText(stockQuote.getVolumePrice() + "");
		typeValue.setText(stockQuote.getType() + "");
		methodValue.setText(stockQuote.getMethod() + "");

		/** Handling chart */
		/*
		 * String imgUrl = "http://finance.google.com/finance/chart?q=NASDAQ:" +
		 * stockQuote.getSymbol() + "&tlf=12"; Drawable image =
		 * getDrawableImage(imgUrl); ImageView imgView = (ImageView)
		 * findViewById(R.id.chartImageView); imgView.setImageDrawable(image);
		 */

	}

	private void setChangeInformation(StockQuote stockQuote, TextView textView,
			ImageView imageView) {
		String change = String.valueOf(Math.abs(stockQuote.getChangePercent()));
		textView.setText(change);

		if (stockQuote.getChangePercent() > 0) {
			textView.setTextColor(Color.GREEN);
			imageView.setImageResource(R.drawable.green);
		} else if (stockQuote.getChangePercent() < 0) {
			textView.setTextColor(Color.RED);
			imageView.setImageResource(R.drawable.red);
		} else {
			textView.setTextColor(Color.WHITE);
		}
	}

	public boolean onKey(View arg0, int keyCode, KeyEvent arg2) {
		if (keyCode == KeyEvent.KEYCODE_ENTER) {
			if (arg0 == symbolWidget) {
				return getQuoteButton.performClick();
			} else if (arg0 == myPortfolioWidget) {
				return addSymbolButton.performClick();
			} else {
				throw new RuntimeException("Unknown Key Click event");
			}
		} else {
			return false;
		}
	}

	private void assignRowColor(final TableLayout tableLayout) {
		int childCount = tableLayout.getChildCount();
		for (int i = 1; i < childCount; i++) {
			TableRow iRow = (TableRow) tableLayout.getChildAt(i);
			if (i % 2 == 0) {
				iRow.setBackgroundColor(Color.parseColor("#333333"));
			} else {
				iRow.setBackgroundColor(Color.parseColor("#222222"));
			}
		}
	}

	void deleteShareFromUserAccount(String symbol) {
		List<Share> toRemove = new LinkedList<Share>();
		for (Share share : user.getAccount().getShares()) {
			if (share.getSymbol().equalsIgnoreCase(symbol))
				toRemove.add(share);
		}
		Account account = accountProvider.deleteSharesFromUserAccount(username,
				toRemove);
		user.setAccount(account);
	}

	void addShareToUserAccount(String symbol) {
		List<Share> shares = new LinkedList<Share>();
		Share share = new ShareBean();
		share.setSymbol(symbol);
		shares.add(share);
		Account account = accountProvider.addSharesToUserAccount(username,
				shares);
		user.setAccount(account);
	}
	/** Graph image provider */
	// private Drawable getDrawableImage(String url) {
	// try {
	// InputStream is = (InputStream) this.fetch(url);
	// Drawable d = Drawable.createFromStream(is, "src");
	// return d;
	// } catch (MalformedURLException e) {
	// e.printStackTrace();
	// return null;
	// } catch (IOException e) {
	// e.printStackTrace();
	// return null;
	// }
	// }

	// public Object fetch(String address) throws MalformedURLException,
	// IOException {
	// URL url = new URL(address);
	// Object content = url.getContent();
	// return content;
	// }
}